#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

// ??????,??0-9??'-'?
uchar code smgduan[] = {
    0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
    0x7f, 0x6f, 0x40  // 40??'-'?
};

// ?????????
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

// ??????
sbit key1 = P3^2;  // ??K1?P3.2??????
sbit key2 = P3^3;  // ??K2?P3.3??????
sbit key3 = P3^4;  // ??K3?P3.4?????

// ????
uchar hour = 13, minute = 59, second = 55;

// ????
void Delay(uint i)
{
    while(i--);
}

// ???????
void DigDisplay()
{
    uchar i;
    for(i = 0; i < 8; i++)
    {
        switch(i)  // ??,????????
        {
            case(0):
                LSA = 0; LSB = 0; LSC = 0; break; // ???0?
            case(1):
                LSA = 1; LSB = 0; LSC = 0; break; // ???1?
            case(2):
                LSA = 0; LSB = 1; LSC = 0; break; // ???2?
            case(3):
                LSA = 1; LSB = 1; LSC = 0; break; // ???3?
            case(4):
                LSA = 0; LSB = 0; LSC = 1; break; // ???4?
            case(5):
                LSA = 1; LSB = 0; LSC = 1; break; // ???5?
            case(6):
                LSA = 0; LSB = 1; LSC = 1; break; // ???6?
            case(7):
                LSA = 1; LSB = 1; LSC = 1; break; // ???7?    
        }
        P0 = smgduan[hour / 10];  // ???????
        Delay(500);  // ??
        P0 = 0x00;

        P0 = smgduan[hour % 10];  // ???????
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[10];  // ????? '-'
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[minute / 10];  // ???????
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[minute % 10];  // ???????
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[10];  // ????? '-'
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[second / 10];  // ??????
        Delay(500);
        P0 = 0x00;

        P0 = smgduan[second % 10];  // ??????
        Delay(500);
        P0 = 0x00;		
    }	
}

// ???T1?????,?????????(??????)
void Timer1Init(void)		//1ms@11.0592MHz
{
    TMOD |= 0x10;		//?????T1???1(16????)
    TH1 = 0xFC;		//???????,??1ms
    TL1 = 0x18;
    ET1 = 1;		//?????1??
    TR1 = 1;		//?????1
    EA = 1;			//?????
}

// ???T1??????,???????????
void Timer1() interrupt 3
{
    static uchar i = 0;
    TH1 = 0xFC;  // ?????
    TL1 = 0x18;
    i++;
    if (i == 200)  // ??1????(1ms * 200 = 200ms,??????,?????????)
    {
        i = 0;
        DigDisplay();  // ?????????
    }
}

// ??????,?????
uchar KeyScan()
{
    uchar keyValue = 0;
    if (key1 == 0)
    {
        Delay(10);  // ????
        if (key1 == 0)
        {
            while (!key1);  // ??????
            keyValue = 1;  // ????
        }
    }
    else if (key2 == 0)
    {
        Delay(10);
        if (key2 == 0)
        {
            while (!key2);
            keyValue = 2;  // ????
        }
    }
    else if (key3 == 0)
    {
        Delay(10);
        if (key3 == 0)
        {
            while (!key3);
            keyValue = 3;  // ???
        }
    }
    return keyValue;
}

// ????1?????
void ExternInt1Init(void)
{
    IT1 = 1;  // ?????????1
    EX1 = 1;  // ??????1
    EA = 1;   // ?????
}

// ????1????,?????15:45:58
void ExternInt1() interrupt 2
{
    hour = 15;
    minute = 45;
    second = 58;
}

void main(void)
{
    uchar key;
    Timer1Init();  // ??????T1
    ExternInt1Init();  // ???????1

    while(1)
    {
        key = KeyScan();
        switch(key)
        {
            case 1:
                hour++;
                if (hour >= 24) hour = 0;  // ????23???
                break;
            case 2:
                minute++;
                if (minute >= 60) minute = 0;  // ????59???
                break;
            case 3:
                second++;
                if (second >= 60) second = 0;  // ???59???
                break;
        }
    }
}